package com.example.hydrogengenerator.ext

import android.content.Context
import android.graphics.Bitmap
import android.text.TextUtils
import android.view.View
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import android.widget.ImageView
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.lifecycle.LifecycleCoroutineScope
import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.lifecycle.lifecycleOwner
import com.bumptech.glide.Glide
import com.bumptech.glide.load.MultiTransformation
import com.bumptech.glide.load.resource.bitmap.*
import com.bumptech.glide.request.RequestOptions
import com.google.gson.GsonBuilder
import com.google.gson.TypeAdapter
import com.google.gson.stream.JsonReader
import com.google.gson.stream.JsonToken
import com.google.gson.stream.JsonWriter
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.*
import me.hgj.jetpackmvvm.base.appContext
import me.hgj.jetpackmvvm.ext.util.dp2px
import java.io.BufferedReader
import java.io.FileReader
import java.io.IOException
import java.math.BigDecimal
import java.math.RoundingMode
import java.text.SimpleDateFormat
import java.util.*
import java.util.regex.Pattern

var regEx = ("^(([\\w-]+\\.)+[\\w-]+|([a-zA-Z]{1}|[\\w-]{2,}))@"
        + "((([0-1]?[0-9]{1,2}|25[0-5]|2[0-4][0-9])\\.([0-1]?"
        + "[0-9]{1,2}|25[0-5]|2[0-4][0-9])\\."
        + "([0-1]?[0-9]{1,2}|25[0-5]|2[0-4][0-9])\\.([0-1]?"
        + "[0-9]{1,2}|25[0-5]|2[0-4][0-9])){1}|"
        + "([a-zA-Z]+[\\w-]+\\.)+[a-zA-Z]{2,4})$")

/*
* 验证Email是否合法
* */
fun String.validateEmailAddress(): Boolean {
    return Pattern.compile(regEx).matcher(this.trim()).matches()
}


//view 转bitmap
fun convertViewToBitmap(view: View): Bitmap? {
    view.measure(
        View.MeasureSpec.makeMeasureSpec(
            0,
            View.MeasureSpec.UNSPECIFIED
        ),
        View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
    )
    view.layout(0, 0, view.measuredWidth, view.measuredHeight)
    view.buildDrawingCache()
    return view.drawingCache
}


/**
 * @param message 显示对话框的内容 必填项
 * @param title 显示对话框的标题 默认 温馨提示
 * @param positiveButtonText 确定按钮文字 默认确定
 * @param positiveAction 点击确定按钮触发的方法 默认空方法
 * @param negativeButtonText 取消按钮文字 默认空 不为空时显示该按钮
 * @param negativeAction 点击取消按钮触发的方法 默认空方法
 *
 */
fun AppCompatActivity.showMessage(
    message: String,
    title: String = "温馨提示",
    positiveButtonText: String = "确定",
    positiveAction: () -> Unit = {},
    negativeButtonText: String = "",
    negativeAction: () -> Unit = {}
) {
    MaterialDialog(this)
        .cancelable(false)
        .lifecycleOwner(this)
        .show {
            title(text = title)
            message(text = message)
            positiveButton(text = positiveButtonText) {
                positiveAction.invoke()
            }
            if (negativeButtonText.isNotEmpty()) {
                negativeButton(text = negativeButtonText) {
                    negativeAction.invoke()
                }
            }
        }
}

/**
 * @param message 显示对话框的内容 必填项
 * @param title 显示对话框的标题 默认 温馨提示
 * @param positiveButtonText 确定按钮文字 默认确定
 * @param positiveAction 点击确定按钮触发的方法 默认空方法
 * @param negativeButtonText 取消按钮文字 默认空 不为空时显示该按钮
 * @param negativeAction 点击取消按钮触发的方法 默认空方法
 */
fun Fragment.showMessage(
    message: String,
    title: String = "温馨提示",
    positiveButtonText: String = "确定",
    positiveAction: () -> Unit = {},
    negativeButtonText: String = "",
    negativeAction: () -> Unit = {}
) {
    activity?.let {
        MaterialDialog(it)
            .cancelable(false)
            .lifecycleOwner(viewLifecycleOwner)
            .show {
                title(text = title)
                message(text = message)
                positiveButton(text = positiveButtonText) {
                    positiveAction.invoke()
                }
                if (negativeButtonText.isNotEmpty()) {
                    negativeButton(text = negativeButtonText) {
                        negativeAction.invoke()
                    }
                }
            }
    }
}

/**
 * 获取进程号对应的进程名
 *
 * @param pid 进程号
 * @return 进程名
 */
fun getProcessName(pid: Int): String? {
    var reader: BufferedReader? = null
    try {
        reader = BufferedReader(FileReader("/proc/$pid/cmdline"))
        var processName = reader.readLine()
        if (!TextUtils.isEmpty(processName)) {
            processName = processName.trim { it <= ' ' }
        }
        return processName
    } catch (throwable: Throwable) {
        throwable.printStackTrace()
    } finally {
        try {
            reader?.close()
        } catch (exception: IOException) {
            exception.printStackTrace()
        }

    }
    return null
}


fun List<*>?.isNull(): Boolean {
    return this?.isEmpty() ?: true
}

fun List<*>?.isNotNull(): Boolean {
    return this != null && this.isNotEmpty()
}

fun Double.toBigDecimalPrice(): BigDecimal {
    return this.toBigDecimal().setScale(2, RoundingMode.HALF_UP)
}

fun Long.getTimeFormat(format: String = "hh:mm aa dd/MM/yyyy"): String {
    return SimpleDateFormat(
        format,
        Locale.ENGLISH
    ).format(Date(if (this < 1 * 1000000000000) this * 1000L else this))
}

fun Date.getTimeFormat(format: String = "yyyy-MM-dd"): String {
    return SimpleDateFormat(
        format,
        Locale.ENGLISH
    ).format(this)
}

/*
* 获取焦点 并弹起输入法
* */
fun EditText.requestFocusable() {
    isFocusable = true
    requestFocus()
    //打开软键盘
    val imm: InputMethodManager = context
        .getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
    imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS)
}

/**
 * 根据索引获取集合的child值
 * @receiver List<T>?
 * @param position Int
 * @return T?
 */
inline fun <reified T> List<T>?.getChild(position: Int): T? {
    //如果List为null 返回null
    return if (this == null) {
        null
    } else {
        //如果position大于集合的size 返回null
        if (position + 1 > this.size) {
            null
        } else {
            //返回正常数据
            this[position]
        }
    }
}

//Imageview
fun ImageView.loadImage(url: String?, default: Int = -1) {
    Glide.with(this).load(url).apply(
        RequestOptions().placeholder(default).centerCrop()
    )/*.transition(DrawableTransitionOptions.withCrossFade(500))*/.into(this)
}

fun ImageView.circleImageUrl(url: String?) {
    Glide.with(this.context)
        .load(url)
        .apply(RequestOptions().centerCrop().transform(CircleCrop()))
//        .placeholder(R.drawable.hodler_circle)
        /*.transition(DrawableTransitionOptions.withCrossFade(500))*/
        .into(this)
}

//fun ImageView.circleImageUrlWithBorder(url: String?,border: Int = 1) {
//    this.tag = url
//    if (border == 0) return circleImageUrl(url)
//    Glide.with(this.context)
//        .load(url)
//        .apply(RequestOptions().centerCrop().transform(GlideCircleTransformWithBorderUtils(context,border,0xff09c6b7.toInt())))
//        .into(this)
//}

fun ImageView.loadImageWithTopCorner(url: String?, corner: Int, default: Int = -1, transformation: BitmapTransformation = CenterCrop()) {
    Glide.with(this).load(url).apply(
        RequestOptions.bitmapTransform(
            MultiTransformation(
                transformation,
                GranularRoundedCorners(dp2px(corner).toFloat(), dp2px(corner).toFloat(), 0f, 0f)
            )
        )
            .placeholder(default)
    )/*.transition(DrawableTransitionOptions.withCrossFade(500))*/.into(this)
}

//Imageview
fun ImageView.loadImageWithCorner(url: String?, corner: Int, default: Int = -1, transformation: BitmapTransformation = CenterCrop()) {
    Glide.with(this).load(url).apply(
        RequestOptions.bitmapTransform(MultiTransformation(transformation, RoundedCorners(dp2px(corner)))).placeholder(default)
    )/*.transition(DrawableTransitionOptions.withCrossFade(500))*/.into(this)
}

fun Int.str() = appContext.getString(this)

val gson by lazy {
    GsonBuilder().registerTypeAdapter(String::class.java, object : TypeAdapter<String>() {
        override fun write(out: JsonWriter?, value: String?) {
            out?.value(value)
        }

        override fun read(`in`: JsonReader?): String {
            if (`in`?.peek() == JsonToken.NULL) {
                `in`.nextNull()
                return ""
            }
            val result = `in`?.nextString()
            return if (result.isNullOrEmpty()) {
                ""
            } else
                result
        }
    }).create()
}

/**
 * @param total 总时间 单位根据步长计算
 * @param step 步长 默认 单位是毫秒 1000毫秒
 * @param onTick 每秒回调
 * @param onFinish 完成回调
 */
fun LifecycleCoroutineScope.timerCoroutines(total: Long, step: Long = 1000, onTick: (Long) -> Unit, onFinish: () -> Unit): Job {
    return flow {
        for (i in 0..total step step) {
            emit(total - i)
            delay(1000)
        }
    }.flowOn(Dispatchers.Main)
        .onCompletion { onFinish.invoke() }
        .onEach { onTick.invoke(it) }
        .flowOn(Dispatchers.Main)
        .catch {
        }
        .launchIn(this)
}